package john.walker;

import java.io.PrintWriter;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Set;

/**
 * 连接泄露监控工具
 *
 * @author 30san
 *
 */
public class Monitor {

	private static Monitor monitor;

	/**
	 * 未关闭的数据库连接，IdentityHashMap的key只有在满足k1==k2时，才判定相等，不需要满足k1==k2 && k1.equals(k2)条件
	 */
	private IdentityHashMap<ProxyConnection, Object> notClosedConnections = new IdentityHashMap<ProxyConnection, Object>();

	protected final static Object PRESENT                                 = new Object();

	private Monitor() { }

	public static Monitor getMonitor() {
		if(monitor == null) {
			synchronized (Monitor.class) {
				if(monitor == null) {
					monitor = new Monitor();
				}
			}
		}
		return monitor;
	}


	public void removeConnection(ProxyConnection con) {
		if(con != null) {
			getMonitor().notClosedConnections.remove(con);
		}
	}


	public void addConnection(ProxyConnection con) {
		if(con != null) {
			getMonitor().notClosedConnections.put(con, PRESENT);
		}
	}


	/**
	 * 打印连接泄露点
	 */
	public void printStackTrace(PrintWriter out) {
		Set<ProxyConnection> sets = new HashSet<ProxyConnection>(notClosedConnections.keySet());
		out.println("当前未关闭的数据库连接总数 " + sets.size() + "，调用栈如下： ");
		out.println();
		int i = 1;
		for(ProxyConnection con : sets) {
			out.println("第 " + (i++) + " 个连接：");
			con.printConnectionStackTrace(out);
			out.println();
		}
	}

}
